<

ロードシーケンス、パフォーマンス、メモリ

このページでは、関連する手順の内訳について説明します Flutter UI を表示します。これを知ればもっと良くなる、 Flutter エンジンをいつプレウォームするかについて、より多くの情報に基づいた決定が可能になります。 どの段階でどの操作が可能か、 そしてそれらの操作のレイテンシとメモリコスト。

flutterをロード中

Android および iOS アプリ (サポートされている 2 つのプラットフォーム) 既存のアプリへの統合)、完全な Flutter アプリ、 アプリへの追加パターンにも同様のシーケンスがあります。 Flutter UI を表示するときの概念的な読み込み手順。

Flutter リソースを見つける

Flutter のエンジン ランタイムとアプリケーションのコンパイル Dart コードは両方とも Android の共有ライブラリとしてバンドルされています そしてiOS。 Flutter をロードする最初のステップは、それらを見つけることです。 .apk/.ipa/.app 内のリソース (他の Flutter とともに) 該当する場合、画像、フォント、JIT コードなどのアセット)。

これは、FlutterEngineのために どちらも初めてアンドロイドiOSAPI。

Flutterライブラリのロード

見つかった後、エンジンの共有ライブラリがメモリにロードされます プロセスごとに 1 回。

の上アンドロイド、これは次の場合にも発生します。FlutterEngineが構築されるのは、 JNI コネクタは Flutter C++ ライブラリを参照する必要があります。 の上iOS、これは次のときに発生します。FlutterEngine最初の実行では、 走るなどしてrunWithEntrypoint:

Dart VM の起動

Dart ランタイムは Dart メモリと Dart コードの同時実行性。 JITモードでは、 さらにコンパイルも担当します Dart のソース コードを実行時にマシン コードに変換します。

アプリケーション セッションごとに単一の Dart ランタイムが存在します。 アンドロイドとiOS。

1 回限りの Dart VM の起動は、FlutterEngine初めてアンドロイドそしていつDart エントリポイントの実行初めてiOS

この時点で、Dart コードのスナップショットアプリケーションのファイルからメモリにもロードされます。

これは、ダーツSDKFlutter エンジンを使わずに直接。

Dart VM は、起動後にシャットダウンすることはありません。

Dart Isolate の作成と実行

Dart ランタイムが初期化された後、 Flutter エンジンによる Dart の使用法 ランタイムは次のステップです。

これは、ダーツIsolateDart ランタイムで。 アイソレートは、Dart のメモリとスレッドのコンテナです。 いくつかの補助ねじホストプラットフォーム上では この時点で、isolate をサポートするためにも作成されました。 GPU 処理をオフロードするためのスレッドと、画像デコード用のスレッドとして。

1 つにつき 1 つの分離株が存在します。FlutterEngineインスタンスと複数の分離 同じ Dart VM でホストできます。

の上アンドロイド、これは電話をかけると起こりますDartExecutor.executeDartEntrypoint()FlutterEngine実例。

の上iOS、これは電話をかけると起こりますrunWithEntrypoint:FlutterEngine

この時点で、Dart コードの選択したエントリポイントは (main()Dart ライブラリの機能main.dartファイル、 デフォルトでは) が実行されます。あなたが電話した場合、 flutter関数runApp()あなたの中でmain()関数、 Flutter アプリまたはライブラリのウィジェット ツリーも作成されます そして建てられました。特定の機能の実行を防止する必要がある場合 Flutter コード内で、AppLifecycleState.detachedenum 値は、FlutterEngine付いていない などの UI コンポーネントにFlutterViewControlleriOS またはFlutterActivityアンドロイドで。

Flutter エンジンに UI を接続する

標準の完全な Flutter アプリは、次のようにしてこの状態に到達します。 アプリを起動するとすぐに。

アプリに追加するシナリオでは、 これは、FlutterEngineを呼び出すなどして UI コンポーネントにアクセスするstartActivity()Intentを使用して構築されたFlutterActivity.withCachedEngine()の上アンドロイド。または、FlutterViewControllerを使用して初期化されましたinitWithEngine: nibName: bundle:の上iOS

これは、Flutter UI コンポーネントが何もせずに起動された場合にも当てはまります。 事前に温めるFlutterEngineなどFlutterActivity.createDefaultIntent()の上アンドロイド、 または一緒にFlutterViewController initWithProject: nibName: bundle:の上iOS。暗黙的なFlutterEngineこのような場合に作成されます。

両方のプラットフォームの UI コンポーネントは舞台裏で次の機能を提供します。FlutterEngineのようなレンダリング サーフェスを使用して、Surfaceの上アンドロイドまたはCAEAGLレイヤーまたCAメタルレイヤーの上iOS

この時点で、LayerFlutter によって生成されたツリー プログラムはフレームごとに次のように変換されます。 OpenGL (または Vulkan または Metal) GPU 命令。

メモリと遅延

Flutter UI の表示には、少なからぬレイテンシ コストがかかります。 このコストは、Flutter エンジンを開始することで削減できます。 事前に。

アプリに追加するシナリオに最も適切な選択肢は次のとおりです。 いつプリロードするかを決定するにはFlutterEngine(つまり、Flutter ライブラリをロードするには、Dart VM を起動し、 分離でエントリポイントを実行します)、メモリとレイテンシは何ですか コストはその前のウォームのものです。また、プレウォームがどのように行われるかを知る必要があります。 最初の Flutter をレンダリングする際のメモリとレイテンシのコストに影響します UI コンポーネントが後でアタッチされるときのフレーム それに対してFlutterEngine

Flutter v1.10.3 以降、ローエンド 2015 クラスのデバイスでテスト中 リリース AOT モードでは、プレウォーミングFlutterEngine費用:

  • プリウォームには 42 MB と 1530 ミリ秒アンドロイド。 そのうちの 330 ミリ秒は、メインスレッドでのブロッキング呼び出しです。
  • プリウォームに 22 MB と 860 ミリ秒iOS。 そのうちの 260 ミリ秒は、メインスレッドでのブロッキング呼び出しです。

Flutter UI はプレウォーム中に接続できます。 残りの時間は、最初のフレームまでの時間の遅延に加算されます。

メモリ的には、コスト サンプル (変数、 ユースケースに応じて)次のようになります。

  • pthread の作成に最大 4 MB の OS のメモリ使用量。
  • 約 10 MB の GPU ドライバー メモリ。
  • Dart ランタイム管理メモリの場合は最大 1 MB。
  • Dart に読み込まれたフォント マップの場合は最大 5 MB。

レイテンシの観点からは、 コストサンプル (ユースケースによって異なります) は次のとおりです。

  • アプリケーション パッケージから Flutter アセットを収集するのに約 20 ミリ秒かかります。
  • Flutter エンジン ライブラリを開くのに約 15 ミリ秒かかります。
  • Dart VM の作成と AOT スナップショットのロードに約 200 ミリ秒かかります。
  • Flutter 依存のフォントとアセットをロードするのに最大 200 ミリ秒かかります。
  • エントリポイントの実行、最初のウィジェット ツリーの作成に約 400 ミリ秒かかります。 必要な GPU シェーダ プログラムをコンパイルします。

FlutterEngine十分遅くしてから予熱する必要があります。 メモリ消費は必要ですが、メモリの結合を避けるのに十分な早さです。 最初のフレーム レイテンシでの flutter エンジンの起動時間 flutterを表示します。

正確なタイミングは、アプリの構造とヒューリスティックによって異なります。 例としては、Flutter エンジンを画面にロードすることです。 Flutterによって画面が描画される前。

エンジンが事前に暖気されているとすると、UI アタッチ時の最初のフレーム コストは次のようになります。

  • 320ミリ秒後アンドロイドさらに 12 MB (画面の物理ピクセル サイズに大きく依存します)。
  • 200ミリ秒後iOSさらに 16 MB (画面の物理ピクセル サイズに大きく依存します)。

メモリに関しては、主に、次の処理に使用されるグラフィック メモリ バッファがコストとなります。 レンダリングは画面サイズに依存します。

レイテンシーの観点から見ると、コストは主に OS コールバックが提供するのを待つことにあります。 レンダリング サーフェスを使用した flutterと残りのシェーダー プログラムのコンパイル 事前に予測できないもの。これは 1 回限りの費用です。

Flutter UI コンポーネントがリリースされると、UI 関連のメモリが解放されます。 これは、 flutter状態には影響しません。FlutterEngine(ただし、FlutterEngineも発売されています)。

複数の作成時のパフォーマンスの詳細については、FlutterEngine、 見る複数の flutter